from collections import Counter
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import numpy as np
from matplotlib import style

# Paper specific settings
STANDARD_WIDTH = 17.8
SINGLE_COL_WIDTH = STANDARD_WIDTH / 2
DOUBLE_COL_WIDTH = STANDARD_WIDTH  # 一个图片里面放两个图


def cm_to_inch(value):
    return value / 2.54


# matplotlib style settings
matplotlib.rcParams['text.usetex'] = False
style.use('seaborn-white')
plt.rcParams["axes.grid"] = True
plt.rcParams["axes.grid.axis"] = "both"
plt.rcParams["grid.linewidth"] = 0.8
plt.rcParams['hatch.linewidth'] = 0.5
# plt.rcParams["font.family"] = "Nimbus Roman"
FONTSIZE = 8
ENCODING = 'utf8'

def hashCountBlkparse(path: str):
    cnt = 0
    shitCnt = 0
    hashCounter = Counter()
    with open(path, 'r', encoding=ENCODING) as f:
        for line in f:
            elems = line.strip().split(' ')
            blk, rw, hash_line = int(elems[4]), elems[5], elems[8]

            if blk % 8 != 0:
                shitCnt += 1
                continue

            blkCnt = blk // 8
            cnt += blkCnt
            if rw == 'W':
                for j in range(0, len(hash_line), len(hash_line) // blkCnt):
                    hashCounter[hash_line[j:j+len(hash_line) // blkCnt]] += 1
            else:
                print("Error: not W")

    assert cnt == sum(hashCounter.values())
    return hashCounter.values()

def hashCountHitsztrace(path: str):
    # 获取每个哈希的出现次数
    hashCounter = Counter()
    with open(path, 'r', encoding=ENCODING) as f:
        for line in f:
            elems = line.strip().split(' ')
            lbn, dataHash = int(elems[2]), elems[3]
            hashCounter[dataHash] += 1
    
    return hashCounter.values()


def drawHashCdf():
    """哈希值的cdf图(四张一起)
    """
    traceNameList = ['hitsz', 'homes', 'mail', 'web', 'Nexus-5X']
    traceList = list(map(lambda x: f"{x}_16GB.hitsztrace", traceNameList))
    for i in range(len(traceList)):
        trace = f"./16/{traceList[i]}"
        name = traceNameList[i]
        print(trace)
        if trace.endswith('.hitsztrace'):
            values = hashCountHitsztrace(trace)
        else:
            values = hashCountBlkparse(trace)
        # values: 各个哈希值的频数
        values = list(values)
        with open(f"{name}.txt", 'w', encoding=ENCODING) as f:
            f.write(str(values))
        pdf = np.zeros(max(values) + 1)  # 横轴为频数(1 到 最大频数), 0号位置就放一个0
        for value in values:
            pdf[value] += 1  # 该频数占总频数的比例, 确保pdf总和为sum(values), 即总的哈希值个数

        # 计算cdf
        cdf = np.cumsum(pdf) / sum(pdf)
        # 画图
        plt.plot(np.arange(len(cdf)), cdf, label=name)#, color=colors[traceList.index(trace)])

    plt.xlabel("repetition")
    plt.ylabel('Probability')
    plt.ylim((0, 1.1))
    xMax = 100
    plt.xlim((-xMax // 20, xMax))
    # plt.title(name)
    plt.legend()
    plt.savefig(f"HashCdfAll.png")
